//
//  NetworkClient.m
//  StoreManagement
//
//  Created by centling on 16/5/14.
//  Copyright © 2016年 alfred. All rights reserved.
//

#import "NetworkClient.h"
#import <objc/runtime.h>
#import "NSDictionary+mutableDeepCopy.h"

@implementation NetworkClient

/**
 *  对AFHTTPSessionManager启用单例模式
 *
 *  @return 单例
 */
+ (AFHTTPSessionManager*)sharedHTTPSessionManager{
    static AFHTTPSessionManager* mgr = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        configuration.timeoutIntervalForRequest = 30;
        NSURL* baseURL = [NSURL URLWithString:baseUrl];
        mgr = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL sessionConfiguration:configuration];
        mgr.requestSerializer = [AFJSONRequestSerializer serializer];
        mgr.responseSerializer = [AFHTTPResponseSerializer serializer];
        //        [mgr.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
        mgr.responseSerializer.acceptableContentTypes = [mgr.responseSerializer.acceptableContentTypes setByAddingObjectsFromArray:@[@"text/html",@"application/json"]];
    });
    return mgr;
}


+ (BOOL)checkRetry:(NSNumber*)retryCount{
    return retryCount.integerValue > 0;
}

//added by Alfred
+ (void)requestWithUrl:(NSString*)url
                   params:(NSDictionary*)params
                 filePath:(NSData *)filePath
            fileParamKey:(NSString *)fileParamKey
                  success:(void (^)(id response))success
                  failure:(void (^)(NSError* err))failure {
    AFHTTPSessionManager* mgr = [self sharedHTTPSessionManager];
    [mgr POST:url
   parameters:params
constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
    [formData appendPartWithFileData:filePath name:fileParamKey fileName:@"img.jpg" mimeType:@"image/jpeg"];
}
      success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
          NSDictionary *result = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
          //                  NSDictionary* result = responseObject;
          result = [result mutableDeepCopy];
          [GlobalUtil deepCleanCollection:result];
          if (success) {
              success(result);
          }
      } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
          failure(error);
      }];
}

//used to send form-data
+ (void)requestWithUrl:(NSString*)url
                params:(NSDictionary*)params
               success:(void (^)(id response))success
               failure:(void (^)(NSError* err))failure {
    AFHTTPSessionManager* mgr = [self sharedHTTPSessionManager];
    NSArray *paramKeyArray = [params allKeys];
    NSArray *paramValueArray = [params allValues];
    [mgr POST:url
   parameters:params
constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
    for (int i = 0; i < paramKeyArray.count; i ++) {
        NSMutableData *mutData = [[NSMutableData alloc] init];
        [mutData appendData:[[NSString stringWithFormat:@"%@", paramValueArray[i]] dataUsingEncoding:NSUTF8StringEncoding]];
        [formData appendPartWithFormData:mutData name:paramKeyArray[i]];
    }
}
      success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
          NSDictionary *result = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
          //                  NSDictionary* result = responseObject;
          result = [result mutableDeepCopy];
          [GlobalUtil deepCleanCollection:result];
          if (success) {
              success(result);
          }
      } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
          failure(error);
      }];
}







+ (void)requestWihtMethod:(RequestMethodType)methodType
                      url:(NSString*)url
                   params:(NSDictionary*)params
                  success:(void (^)(id response))success
                  failure:(void (^)(NSError* err))failure
{
    
    //    if(![AFNetworkReachabilityManager sharedManager].isReachable){
    //        UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"无网络，请重新连接" message:@"" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles: nil];
    //        [alert show];
    //        return;
    //    }
    
    AFHTTPSessionManager* mgr = [self sharedHTTPSessionManager];
    //    NSString *token =[[NSUserDefaults standardUserDefaults] objectForKey:TOKEN];
    //    NSMutableString *authHeader=[[NSMutableString alloc] initWithString:@"Bearer "];
    //    token.length>10?[authHeader appendString:token]:nil;
    //    [mgr.requestSerializer setValue:authHeader forHTTPHeaderField:@"Authorization"];
    
    //拼接标识Request的Key
    NSString* requestID = [NSString stringWithFormat:@"%@:%@", @(methodType), url];
    NSNumber* retryCount = objc_getAssociatedObject(mgr, [requestID UTF8String]);
    if (!retryCount) {
        retryCount = @(3);
    } else {
        retryCount = @(retryCount.integerValue - 1);
    }
    objc_setAssociatedObject(mgr, [requestID UTF8String], retryCount, OBJC_ASSOCIATION_COPY);
    switch (methodType) {
        case RequestMethodTypeGet:{
            //GET请求
            [mgr GET:url
          parameters:params
             success:^(NSURLSessionDataTask *task, id responseObject) {
                 NSDictionary *result = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
                 //                 NSDictionary* result = responseObject;
                 result = [result mutableDeepCopy];
                 [GlobalUtil deepCleanCollection:result];
                 if (success) {
                     success(result);
                 }
             }
             failure:^(NSURLSessionDataTask *task, NSError *error) {
                 if (error.code == kCFURLErrorTimedOut && [self checkRetry:retryCount]) {
                     [self requestWihtMethod:methodType
                                         url:url
                                      params:params
                                     success:success
                                     failure:failure];
                 } else {
                     objc_setAssociatedObject(mgr, [requestID UTF8String], nil, OBJC_ASSOCIATION_COPY);
                     failure(error);
                 }
             }];
        }
            break;
        case RequestMethodTypePost:
        {
            //POST请求
            [mgr POST:url
           parameters:params
              success:^(NSURLSessionDataTask *task, id responseObject) {
                  NSDictionary *result = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
                  //                  NSDictionary* result = responseObject;
                  result = [result mutableDeepCopy];
                  [GlobalUtil deepCleanCollection:result];
                  if (success) {
                      success(result);
                  }
              } failure:^(NSURLSessionDataTask *task, NSError *error) {
                  if (error.code == kCFURLErrorTimedOut && [self checkRetry:retryCount]) {
                      [self requestWihtMethod:methodType
                                          url:url
                                       params:params
                                      success:success
                                      failure:failure];
                  } else {
                      objc_setAssociatedObject(mgr, [requestID UTF8String], nil, OBJC_ASSOCIATION_COPY);
                      failure(error);
                  }
              }];
        }
            break;
        case RequestMethodTypeDelete:
        {
            //DELETE请求
            [mgr DELETE:url
             parameters:params
                success:^(NSURLSessionDataTask *task, id responseObject) {
                    //                    NSDictionary* result = responseObject;
                    NSDictionary *result = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
                    result = [result mutableDeepCopy];
                    [GlobalUtil deepCleanCollection:result];
                    if (success) {
                        success(result);
                    }
                } failure:^(NSURLSessionDataTask *task, NSError *error) {
                    if (error.code == kCFURLErrorTimedOut && [self checkRetry:retryCount]) {
                        [self requestWihtMethod:methodType
                                            url:url
                                         params:params
                                        success:success
                                        failure:failure];
                    } else {
                        objc_setAssociatedObject(mgr, [requestID UTF8String], nil, OBJC_ASSOCIATION_COPY);
                        failure(error);
                    }
                }];
        }
            break;
        default:
            break;
    }
}

//取消请求
+ (void) cancelTasks {
    for (NSURLSessionTask *task in [self sharedHTTPSessionManager].tasks) {
        [task cancel];
    }
}

@end
